package com.ht.WeNas.data.vo;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import lombok.Data;

import java.util.List;
import java.util.Objects;
import java.util.function.Function;

@Data
@Schema(description = "分页参数")
public class ResPage<T> {
    @Parameter(description = "当前页码")
    Long current;
    
    @Parameter(description = "每页显示条数")
    Long size;
    
    @Parameter(description = "总数")
    Long total;
    
    @Parameter(description = "当前数据分页总数")
    Long pages;

    @Parameter(description = "查询到的数据")
    List<T> records;
    
    public ResPage(Page<T> page) {
        this.current = page.getCurrent();
        this.size = page.getSize();
        this.records = page.getRecords();
        this.total = page.getTotal();
        this.pages = page.getPages();
    }
    
    private ResPage() {}
    
    public ResPage(long current, long size, long total) {
        this(current, size, total, null);
    }

    public ResPage(long current, long size, long total, List<T> records) {
        this.current = current;
        this.size = size;
        this.total = total;

        if (this.size == 0) {
            this.pages = 0L;
        } else {
            long pages = this.total / this.size;
            if (this.total % this.size != 0) {
                pages++;
            }
            this.pages = pages;
        }
        
        this.records = records;
    }

    public static <T, D> ResPage<T> map(ResPage<D> page, Function<D, T> processor) {
        ResPage<T> res = new ResPage<>();
        res.current = page.current;
        res.size = page.size;
        res.total = page.total;
        res.pages = page.pages;
        if (page.records == null) {
            res.records = null;
        } else {
            res.records = page.records.stream().map(processor).filter(Objects::nonNull).toList();
        }
        return res;
    }

    public static <T, D> ResPage<T> mapList(ResPage<D> page, Function<List<D>, List<T>> processor) {
        ResPage<T> res = new ResPage<>();
        res.current = page.current;
        res.size = page.size;
        res.total = page.total;
        res.pages = page.pages;
        res.records = processor.apply(page.records);
        return res;
    }
    
    /**
     * 根据list创建分页对象
     * @param current 页码
     * @param size 单页数据数量
     * @param list 所有数据
     * @return 分页对象
     * @param <T> 数据类型
     */
    public static <T> ResPage<T> fromList(int current, int size, @Nullable List<T> list) {
        int listSize = 0;
        if (list != null) {
            listSize = list.size();
        }
        if (size == -1) {
            ResPage<T> page = new ResPage<>(1, listSize, listSize);
            page.setRecords(list);
            return page;
        }
        ResPage<T> page = new ResPage<>(current, size, listSize);
        int fromIndex = (current - 1) * size;
        int total = listSize;
        if (fromIndex >= total || fromIndex < 0) {
            page.setRecords(List.of());
        } else {
            List<T> res = list.subList(fromIndex, Math.min(fromIndex + size, total));
            page.setRecords(res);
        }
        return page;
    }
}
